﻿define([
    "dojo/_base/connect",
    "dojo/_base/declare",
    "dojo/_base/lang",
    "dojo/_base/Deferred",
    "dojo/when",

    "dijit/focus",
    "dijit/_CssStateMixin",
    "dijit/_Widget",
    "dijit/_TemplatedMixin",
    "dijit/_WidgetsInTemplateMixin",

    "dijit/Dialog",

// epi.cms
    "epi-cms/widget/_HasChildDialogMixin",
    "epi/epi",
    "epi/dependency",
    "epi/routes",
    "epi/shell/widget/_ValueRequiredMixin",
    "epi/shell/dnd/Target",
    "epi/shell/widget/dialog/Dialog",

    // epi.cms
    "epi-cms/core/ContentReference",
    "epi-cms/core/PermanentLinkHelper",
    "epi-cms/contentediting/ContentActionSupport",
    //"epi-cms/widget/_Droppable",
    "epi-cms/widget/ContentSelectorDialog",

    "dojo/text!./ImageSelector.html",

    "xstyle/css!./ImageSelector.css"

],
function (
    connect,
    declare,
    lang,
    Deferred,
    when,

    focusManager,
    _CssStateMixin,
    _Widget,
    _TemplatedMixin,
    _WidgetsInTemplateMixin,

    BaseDialog,

    _HasChildDialogMixin,
    epi,
    dependency,
    routes,
    _ValueRequiredMixin,
    Target,
    Dialog,

    // epi.cms
    ContentReference,
    PermanentLinkHelper,
    ContentActionSupport,
    //_Droppable,
    //_HasClearButton,
    ContentSelectorDialog,

    template
) {

    return declare("ow-epi-imageProperty.widgets.ImageSelector", [_Widget, _TemplatedMixin, _WidgetsInTemplateMixin, _CssStateMixin, _ValueRequiredMixin, _HasChildDialogMixin], {

        templateString: template,

        helptext: "Select an image",

        intermediateChanges: false,

        baseClass: 'imageExt',

        _dialog: null,

        value: null,

        selectedContent: null,

        postMixInProperties: function () {
            this.inherited(arguments);

            if (this.supportedMediaTypes) {
                this.acceptDataTypes = this.acceptDataTypes || this.supportedMediaTypes;
            }
        },

        postCreate: function () {
            // call base implementation
            this.inherited(arguments);
            this._dropTarget = new Target(this.dropAreaNode, {
                accept: this.acceptDataTypes,
                createItemOnDrop: false,
                readOnly: this.readOnly
            });

            //create drop target
            this.connect(this._dropTarget, "onDropData", "_onDropData");
            this.connect(this._dropTarget, "onDndStart", "_onDragStart");
            this.connect(this._dropTarget, "onDndCancel", "_onDragCancel");

            this.deleteButton.title = this.clearText;
            this.noImageNode.innerHTML = this.browseHtml;
            this.dropAreaNotSupportedNode.innerText = this.supportedFormatsText;

            //size
            dojo.style(this.thumbnail, { "max-width": this.imageSize.width + 'px', "max-height": this.imageSize.height + 'px' });
            dojo.style(this.imagePreviewNode, { width: (this.imageSize.width + 6) + "px", height: (this.imageSize.height + 6) + "px" }); //include borders and paddings
            var userDefinedStyles = { width: this.imageSize.width + "px", height: this.imageSize.height + "px" };
            dojo.style(this.thumbnailContainer, userDefinedStyles);
            dojo.style(this.dropAreaNode, userDefinedStyles);
            dojo.style(this.dropAreaNotSupportedNode, userDefinedStyles);
        },

        isValid: function () {
            // summary:
            //    Check if widget's value is valid.
            // tags:
            //    protected, override

            if (this.required !== true) {
                return true;
            }

            if (this.value == null || this.value == "") {
                return false;
            }

            return true;
        },

        // Setter for value property
        _setValueAttr: function (value) {

            var registry = dependency.resolve("epi.storeregistry");
            var store = registry.get("epi.cms.content.light");
            when(store.get(value), lang.hitch(this, function (content) {
                if (content != null) {
                    this.thumbnail.src = content.publicUrl + "?t=ScaleToFill|" + this.imageSize.width + "x" + this.imageSize.height || "";
                    this._setElementVisibility(this.noImageNode, !value);
                    this._setElementVisibility(this.thumbnailContainer, !!value, 'table-cell');
                    this._setElementVisibility(this.deleteButton, value);
                }
            }));
            this._set("value", value);
        },

        _setReadOnlyAttr: function (value) {
            this._set("readOnly", value);
            this._setElementVisibility(this.deleteButton, !value);
        },

        destroy: function () {
            if (this._dialog) {
                this._dialog.destroyRecursive();
                delete this._dialog;
            }

            this.inherited(arguments);
        },

        onChange: function (value) {
            // Event
        },

        onSelectImage: function () {
            if (this.readOnly) {
                return;
            }

            this.onFocus();
            this._showDialog();
        },

        onDeleteImage: function (evt) {
            if (this.readOnly) {
                return;
            }

            this.set("value", null);

            this._setElementVisibility(this.thumbnailContainer, false);
            this._setElementVisibility(this.deleteButton, false);
            this._setElementVisibility(this.noImageNode, true, 'table-cell');

            evt.preventDefault();
            evt.stopPropagation();
        },

        // SHOW DIALOG WINDOW
        _showDialog: function () {

            var repositoryKey = "media";
            var contentRepositoryDescriptors = dependency.resolve("epi.cms.contentRepositoryDescriptors");
            var settings = contentRepositoryDescriptors[repositoryKey];
            var roots = settings.roots;

            if (this._dialog == null) {
                var contentSelectorDialog = new ContentSelectorDialog({
                    canSelectOwnerContent: false,
                    showButtons: true,
                    roots: roots,
                    showAllLanguages: true,
                    allowedTypes: this.acceptDataTypes
                });

                this.connect(contentSelectorDialog, "onChange", "_setDialogButtonState");

                this._dialog = new Dialog({
                    title: "Select image",
                    dialogClass: "epi-dialog-portrait",
                    content: contentSelectorDialog,
                    destroyOnHide: false,
                    style: "width: 500px;"
                });

                this.connect(this._dialog, 'onHide', this._onDialogHide);
                this.connect(this._dialog, 'onExecute', this._onDialogExecute);
            }
            focusManager.focus(this.thumbnail);

            this.isShowingChildDialog = true;

            if (this.value) {
                this._dialog.content.set('value', this.value);
            }

            this._dialog.show();
        },

        _onDialogExecute: function () {
            this.set('value', this.selectedContent);
            this.onChange(this.selectedContent);
        },

        _setDialogButtonState: function (contentLink) {
            this.selectedContent = contentLink;
        },

        _onDialogHide: function () {
            this.isShowingChildDialog = false;
            this.selectedContent = null;
        },

        // D&D
        _onDragStart: function (source, nodes, copy) {
            if (this.readOnly) {
                return;
            }

            if (nodes.length === 1) {
                var item = source.getItem(nodes[0].id);
                var data = item.data.dndData || item.data;
                if (this.acceptDataTypes.indexOf(data.typeIdentifier) >= 0) {
                    dojo.style(this.dropAreaNode, 'display', 'table-cell');
                } else {
                    dojo.style(this.dropAreaNotSupportedNode, 'display', 'table-cell');
                }
            }
        },

        _onDropData: function (dndData, source, nodes, copy) {

            var dropItem = dndData ? (dndData.length ? dndData[0] : dndData) : null;
            var self = this;
            if (dropItem) {
                dojo.when(dropItem.data, dojo.hitch(this, function (value) {
                    self.set('value', value.contentLink);
                    this._onDrop();
                }));
            }
        },

        _onDragCancel: function () {
            this._onDragEnd();
        },

        _onDragEnd: function () {
            dojo.style(this.dropAreaNode, 'display', 'none');
            dojo.style(this.dropAreaNotSupportedNode, 'display', 'none');
        },

        _onDrop: function () {
            this.onChange(this.value);
            this._onDragEnd();

            focusManager.focus(this.thumbnail);
        },

        // UTILS
        _setElementVisibility: function (node, visible, visibleStyle) {
            if (visible) {
                if (!visibleStyle) {
                    visibleStyle = 'block';
                }
                dojo.style(node, 'display', visibleStyle);
            } else {
                dojo.style(node, 'display', 'none');
            }
        }
    });
});